package com.pancm.test.ffmpeg;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;

/**
 * @author pancm
 * @Title: AudioConverter
 * @Description: 音频格式转换
 * @Version:1.0.0
 * @since 2025/5/12
 */
public class AudioConverter {

    public static void main(String[] args) {

        String filePath = "1 (2).mp3";
        File file =  new File(filePath);
        try {
            if (isM4AFile(file)) {
                System.out.println("检测到M4A格式文件，开始转码...");
                String outputPath = getOutputPath(file);
                convertToMp3(file, new File(outputPath));
                System.out.println("转码完成: " + outputPath);
            } else {
                System.out.println("文件无需处理");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static boolean isM4AFile(File file) throws IOException {
        try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
            if (raf.length() < 12) return false;

            raf.seek(4);
            byte[] ftyp = new byte[4];
            raf.read(ftyp);
            if (!"ftyp".equals(new String(ftyp, StandardCharsets.US_ASCII))) {
                return false;
            }

            raf.seek(8);
            byte[] brand = new byte[4];
            raf.read(brand);
            String brandStr = new String(brand, StandardCharsets.US_ASCII);
            return brandStr.equals("M4A ") || brandStr.equals("mp42")
                || brandStr.equals("isom") || brandStr.equals("M4B ");
        }
    }

    private static String getOutputPath(File inputFile) {
        return inputFile.getAbsolutePath()
                .replaceFirst("\\.[^.]+$", "") + "_converted.mp3";
    }

    private static void convertToMp3(File inputFile, File outputFile)
            throws FFmpegFrameGrabber.Exception, FrameRecorder.Exception {

        try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile)) {
            grabber.start();

            try (FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(
                    outputFile,
                    grabber.getAudioChannels())) {

                recorder.setAudioCodec(avcodec.AV_CODEC_ID_MP3);
                recorder.setSampleRate(grabber.getSampleRate());
                recorder.setAudioBitrate(128000);
                recorder.setFormat("mp3");
                recorder.start();

                Frame frame;
                while ((frame = grabber.grabFrame()) != null) {
                    // 仅处理音频帧
                    if (frame.samples != null) {
                        recorder.record(frame);
                    }
                }
            }
        } catch (FrameGrabber.Exception e) {
            throw new RuntimeException(e);
        }
    }
}